import cherrypy
import os.path
import config
import logging
from string import Template

from cherrypy.lib.static import serve_file

def static_file(filename):
    return serve_file(os.path.join(config.STATIC_DIR, filename))

def template_file(filename, namespace=None, cache={}):
    """Returns a template filled with namespace,
    raises HTTPError when something goes wrong
    
        404: If template file isn't found.
        500: If template filling caused an error.
        Any other exceptions are not caught
    
    Does automatic caching with the help of default arguments,
    set cache to None or an empty dictionary to not use the cache
    """
    namespace = namespace or {}
    cache = cache or {}
    try:
        tp_file = open(os.path.join(config.STATIC_DIR, filename))
        tp_file = tp_file.read()
    except (IOError):
        logging.debug("Template not found: {filename}"\
              .format(filename=filename))
        raise cherrypy.HTTPError(404)
    if (filename in cache):
        template = cache[filename]
    else:
        template = Template(tp_file)
        cache[filename] = template
    try:
        return template.substitute(**namespace)
    except (ValueError):
        logging.debug("Template substitute failed in file: {filename}"\
                      .format(filename=filename))
        raise cherrypy.HTTPError(500)
def get_challenge(length=64):
    """Creates a random string of length length
    user for forms and other things"""
    import random, string
    return ''.join(random.choice(string.letters + string.digits) for i in xrange(length))

def authenticate():
    user = cherrypy.session.get("user", None)
    if not user:
        print "New session"
        cherrypy.session["login_error"] = "Please log in"
        raise cherrypy.HTTPRedirect('/login/')
    
cherrypy.tools.authenticate = cherrypy.Tool('before_handler', authenticate)

class Root(object):
    _cp_config = {'tools.staticdir.on': True,
                  'tools.staticdir.dir': config.STATIC_DIR,
                  'tools.sessions.on': True,
                  }
    @cherrypy.expose
    def login(self, **kwargs):
        if (cherrypy.session.get("user", None)):
            raise cherrypy.HTTPRedirect("/")
        session_challenge = cherrypy.session.get("challenge", None)
        if (not session_challenge):
            cherrypy.session["challenge"] = get_challenge()
        method = cherrypy.request.method
        if (method == "POST"):
            username = kwargs.get('username', None)
            password = kwargs.get('password', None)
            challenge = kwargs.get('challenge', None)
            if (challenge != session_challenge):
                cherrypy.session["login_error"] = "Challenge not correct, please try again"
                raise cherrypy.HTTPRedirect('/login/')
            elif (username == None) or (password == None):
                cherrypy.session["login_error"] = "Forgot username or password"
                raise cherrypy.HTTPRedirect("/login/")
            else:
                if (username == "Test") and (password == "Test"):
                    cherrypy.session['user'] = "Test"
                    raise cherrypy.HTTPRedirect("/")
                else:
                    cherrypy.session['login_error'] = "Wrong username or password"
                    raise cherrypy.HTTPRedirect("/login/")
        else:
            return template_file("login.tmpl", cherrypy.session)
    @cherrypy.expose
    def logout(self, **kwargs):
        if (cherrypy.session.get("user", None)):
            cherrypy.session.clear()
            raise cherrypy.HTTPRedirect("/")
        else:
            raise cherrypy.HTTPRedirect("/")
    @cherrypy.expose
    @cherrypy.tools.authenticate()
    def index(self):
        """Main page, default uses heavy javascript"""
        return "Welcome Home"
        
class API(object):
    """API/Data handlers go here
    
    make sure to expose and authenticate on everything"""
    
cherrypy.config.update(config.CONFIG)
if __name__ == "__main__":
    cherrypy.quickstart(Root())
    cherrypy.root.api = API()
else:
    cherrypy.tree.mount(Root())